home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / fs4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  7.5 KB  |  307 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code to do YCrCb -> colormap space. */
  22.  
  23. #include <config.h>
  24. #include "fs4.h"
  25. #include "video.h"
  26. #include "proto.h"
  27. #include "dither.h"
  28.  
  29. /* Structures containing precomputed error terms. */
  30.  
  31. static FS4Dither lum_index[256];
  32. static FS4Dither cr_index[256];
  33. static FS4Dither cb_index[256];
  34.  
  35.  
  36. /*
  37.  *--------------------------------------------------------------
  38.  *
  39.  * InitFS4Dither --
  40.  *
  41.  *    Initializes structures used for f-s dithering. Precomputes
  42.  *      error terms.
  43.  *
  44.  * Results:
  45.  *    None.
  46.  *
  47.  * Side effects:
  48.  *      None.
  49.  *
  50.  *--------------------------------------------------------------
  51.  */
  52.  
  53. void
  54. InitFS4Dither()
  55. {
  56.   int i;
  57.  
  58.   for (i=0; i<256; i++) {
  59.     lum_index[i].value = (i * LUM_RANGE) / 256;
  60.  
  61.     lum_index[i].e1 = (7 * (i-lum_values[lum_index[i].value])) / 16;
  62.     lum_index[i].e2 = (i-lum_values[lum_index[i].value])/16;
  63.     lum_index[i].e3 = (5 *  (i - lum_values[lum_index[i].value])) / 16;
  64.     lum_index[i].e4 = (i-lum_values[lum_index[i].value]) - lum_index[i].e1 -
  65.       lum_index[i].e2 - lum_index[i].e3;
  66.  
  67.     lum_index[i].value *= LUM_BASE;
  68.  
  69.     cr_index[i].value = (i * CR_RANGE) / 256; 
  70.  
  71.     cr_index[i].e1 = (7 * (i-cr_values[cr_index[i].value])) / 16;
  72.     cr_index[i].e2 = (i-cr_values[cr_index[i].value])/16;
  73.     cr_index[i].e3 = (5 *  (i - cr_values[cr_index[i].value])) / 16;
  74.     cr_index[i].e4 = (i-cr_values[cr_index[i].value]) - cr_index[i].e1 -
  75.       cr_index[i].e2 - cr_index[i].e3;
  76.     cr_index[i].value *= CR_BASE;
  77.  
  78.     cb_index[i].value = (i * CB_RANGE) / 256; 
  79.  
  80.     cb_index[i].e1 = (7 * (i-cb_values[cb_index[i].value])) / 16;
  81.     cb_index[i].e2 = (i-cb_values[cb_index[i].value])/16;
  82.     cb_index[i].e3 = (5 *  (i - cb_values[cb_index[i].value])) / 16;
  83.     cb_index[i].e4 = (i-cb_values[cb_index[i].value]) - cb_index[i].e1 -
  84.       cb_index[i].e2 - cb_index[i].e3;
  85.     cb_index[i].value *= CB_BASE;
  86.  
  87.   }
  88.  
  89. }
  90.  
  91.  
  92. /*
  93.  *--------------------------------------------------------------
  94.  *
  95.  * DitherImage --
  96.  *
  97.  *    Converts lum, cr, cb image planes into fixed colormap
  98.  *      space. Uses Floyd-Steinberg dithering in serpentine
  99.  *      pattern with standard 4 errors propogated.
  100.  *
  101.  * Results:
  102.  *    The display plane is replaced by 8-bit colormap space
  103.  *      image.
  104.  *
  105.  * Side effects:
  106.  *      Hopefully, none.
  107.  *
  108.  *--------------------------------------------------------------
  109.  */
  110.  
  111. void 
  112. FS4DitherImage(lum, cr, cb, disp, rows, cols)
  113.      unsigned char *lum, *cr, *cb, *disp;
  114.      int rows, cols;
  115. {
  116.   static char *cur_row_error, *next_row_error;
  117.   static int first = 1;
  118.   char  *cur_row_err_mark, *next_row_err_mark;
  119.   char *temp;
  120.   int i, j, pixsum, c_cols;
  121.   unsigned char *cur_row, *channel, *dest_row;
  122.   FS4Dither *chan_index;
  123.  
  124.   if (first) {
  125.     cur_row_error = (char *) malloc(cols+2);
  126.     next_row_error = (char *) malloc(cols+2);
  127.     first = 0;
  128.   }
  129.  
  130.   memset(cur_row_error, 0, cols+2);
  131.   memset(next_row_error, 0, cols+2);
  132.  
  133.   for(i=0; i<rows; i+=2) {
  134.      cur_row = lum + (i*cols);
  135.      dest_row = disp + (i*cols);
  136.  
  137.      cur_row_err_mark = cur_row_error + 1;
  138.      next_row_err_mark = next_row_error + 1;
  139.  
  140.      for (j=0; j<cols; j++) {
  141.  
  142.        pixsum = *cur_row + *cur_row_err_mark;
  143.        if (pixsum < 0) pixsum = 0;
  144.        else if (pixsum > 255) pixsum = 255;
  145.  
  146.        *dest_row = lum_index[pixsum].value;
  147.        *(cur_row_err_mark+1) += lum_index[pixsum].e1; 
  148.        *(next_row_err_mark+1) += lum_index[pixsum].e2;
  149.        *next_row_err_mark += lum_index[pixsum].e3; 
  150.        *(next_row_err_mark-1) += lum_index[pixsum].e4;
  151.  
  152.        cur_row++;
  153.        dest_row++;
  154.        cur_row_err_mark++;
  155.        next_row_err_mark++;
  156.      }
  157.  
  158.      temp = cur_row_error;
  159.      cur_row_error = next_row_error;
  160.      next_row_error = temp;
  161.  
  162.      memset(next_row_error, 0, cols+2); 
  163.  
  164.      cur_row += cols-1;
  165.      dest_row += cols-1;
  166.      cur_row_err_mark = cur_row_error + cols;
  167.      next_row_err_mark = next_row_error + cols;
  168.  
  169.      for (j=0; j<cols; j++) {
  170.  
  171.        pixsum = *cur_row + *cur_row_err_mark;
  172.        if (pixsum < 0) pixsum = 0;
  173.        else if (pixsum > 255) pixsum = 255;
  174.  
  175.        *dest_row = lum_index[pixsum].value;
  176.        *(cur_row_err_mark-1) += lum_index[pixsum].e1; 
  177.        *(next_row_err_mark-1) += lum_index[pixsum].e2;
  178.        *next_row_err_mark += lum_index[pixsum].e3; 
  179.        *(next_row_err_mark+1) += lum_index[pixsum].e4;
  180.  
  181.        cur_row--;
  182.        dest_row--;
  183.        cur_row_err_mark--;
  184.        next_row_err_mark--;
  185.      }
  186.  
  187.      temp = cur_row_error;
  188.      cur_row_error = next_row_error;
  189.      next_row_error = temp;
  190.  
  191.      memset(next_row_error, 0, cols+2); 
  192.    }
  193.  
  194.   memset(cur_row_error, 0, cols+2); 
  195.  
  196.   c_cols = cols >> 1;
  197.  
  198.   channel = cr;
  199.   chan_index = cr_index;
  200.  
  201.  repeat:
  202.  
  203.   for (i=0; i < rows; i+=2) {
  204.     cur_row = channel + ((i>>1)*c_cols);
  205.     dest_row = disp + (i*cols);
  206.  
  207.     cur_row_err_mark = cur_row_error+1;
  208.     next_row_err_mark = next_row_error+1;
  209.     
  210.     for (j=0; j<cols; j++) {
  211.       int p_val;
  212.  
  213.       p_val = *cur_row;
  214.  
  215.       pixsum = *cur_row_err_mark + p_val;
  216.  
  217.       if (pixsum < 0) pixsum = 0;
  218.       else if (pixsum > 255) pixsum = 255;
  219.  
  220.       *dest_row += chan_index[pixsum].value;
  221.  
  222.       *(cur_row_err_mark+1) += chan_index[pixsum].e1; 
  223.       *(next_row_err_mark+1) += chan_index[pixsum].e2;
  224.       *next_row_err_mark += chan_index[pixsum].e3; 
  225.       *(next_row_err_mark-1) += chan_index[pixsum].e4;
  226.  
  227.  
  228.       if (j&1) cur_row++;
  229.       dest_row++;
  230.       cur_row_err_mark++;
  231.       next_row_err_mark++;
  232.     }
  233.       
  234.     temp = cur_row_error;
  235.     cur_row_error = next_row_error;
  236.     next_row_error = temp;
  237.  
  238.     memset(next_row_error, 0, cols+2);
  239.  
  240.     cur_row += c_cols-1;
  241.     dest_row += cols-1;
  242.     cur_row_err_mark = cur_row_error+cols;
  243.     next_row_err_mark = next_row_error+cols;
  244.  
  245.     for (j=0; j<cols; j++) {
  246.       int p_val;
  247.  
  248.       p_val = *cur_row;
  249.  
  250.       pixsum = *cur_row_err_mark + p_val;
  251.  
  252.       if (pixsum < 0) pixsum = 0;
  253.       else if (pixsum > 255) pixsum = 255;
  254.  
  255.       *dest_row += chan_index[pixsum].value;
  256.  
  257.       *(cur_row_err_mark-1) += chan_index[pixsum].e1; 
  258.       *(next_row_err_mark-1) += chan_index[pixsum].e2;
  259.       *next_row_err_mark += chan_index[pixsum].e3; 
  260.       *(next_row_err_mark+1) += chan_index[pixsum].e4;
  261.  
  262.       if (j&1) cur_row--;
  263.       dest_row--;
  264.       cur_row_err_mark--;
  265.       next_row_err_mark--;
  266.     }
  267.  
  268.     temp = cur_row_error;
  269.     cur_row_error = next_row_error;
  270.     next_row_error = temp;
  271.  
  272.     memset(next_row_error, 0, cols+2);
  273.   }
  274.  
  275.   if (channel == cr) {
  276.     channel = cb;
  277.     chan_index = cb_index;
  278.     memset(cur_row_error, 0, cols+2);
  279.  
  280.     goto repeat;
  281.   }
  282.  
  283.   dest_row = disp;
  284.  
  285.  
  286.   for (i=0; i<rows; i++) {
  287.     for (j=0; j<cols; j++) {
  288.       *dest_row =  pixel[*dest_row];
  289.       dest_row++;
  290.     }
  291.   }
  292. }
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.